﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using Spring.Objects.Factory.Config;
using Spring.Objects.Factory.Support;
using Strongshell.Recoil.Core.Composition.Parsing.DependencyInjection;
using Strongshell.Recoil.Core.Composition.Parsing.Handlers;

namespace Strongshell.Recoil.Core.Composition.Parsing
{
    public class ExpressionParser : IExpressionParser
    {
        private IExpressionHandler newExpressionHandler;
        private IExpressionHandler memberInitExpressionHandler;
        private IExpressionHandler callExpressionHandler;
        private IExpressionHandler compilingHandler;
        private IExpressionHandler lambdaExpressionHandler;
        private IExpressionHandler listInitExpressionHandler;
        private IExpressionHandler newArrayInitExpressionHandler;

        public IExpressionHandler NewExpressionHandler
        {
            get { return newExpressionHandler; }
            set { newExpressionHandler = value; }
        }

        public IExpressionHandler MemberInitExpressionHandler
        {
            get { return memberInitExpressionHandler; }
            set { memberInitExpressionHandler = value; }
        }

        public IExpressionHandler CallExpressionHandler
        {
            get { return callExpressionHandler; }
            set { callExpressionHandler = value; }
        }

        public IExpressionHandler CompilingHandler
        {
            get { return compilingHandler; }
            set { compilingHandler = value; }
        }

        public IExpressionHandler LambdaExpressionHandler
        {
            get { return lambdaExpressionHandler; }
            set { lambdaExpressionHandler = value; }
        }

        public IExpressionHandler ListInitExpressionHandler
        {
            get { return listInitExpressionHandler; }
            set { listInitExpressionHandler = value; }
        }

        public IExpressionHandler NewArrayInitExpressionHandler
        {
            get { return newArrayInitExpressionHandler; }
            set { newArrayInitExpressionHandler = value; }
        }

        public virtual void Parse(IDependencyInjector currentInjector, Expression currentExpression)
        {
            if(typeof(Expression).IsAssignableFrom(currentInjector.ExpectedType)
                && currentInjector.ExpectedType == currentExpression.GetType())
            {
                currentInjector.Inject(currentExpression);
                return;
            }

            switch (currentExpression.NodeType)
            {
                case ExpressionType.New:
                    newExpressionHandler.Handle(currentInjector, currentExpression);
                    break;
                case ExpressionType.MemberInit:
                    memberInitExpressionHandler.Handle(currentInjector, currentExpression);
                    break;
                case ExpressionType.Call:
                    callExpressionHandler.Handle(currentInjector, currentExpression);
                    break;
                case ExpressionType.Lambda:
                    lambdaExpressionHandler.Handle(currentInjector, currentExpression);
                    break;
                case ExpressionType.ListInit:
                    listInitExpressionHandler.Handle(currentInjector, currentExpression);
                    break;
                case ExpressionType.NewArrayInit:
                    newArrayInitExpressionHandler.Handle(currentInjector, currentExpression);
                    break;
                default:
                    compilingHandler.Handle(currentInjector, currentExpression);
                    break;
            }
        }
    }
}